﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using XAMLStylePad.ViewModels;
using System.Collections.Generic;
using FireFly;

namespace XAMLStylePad.Views
{
    /// <summary>
    /// Interaction logic for ObjectProvider.xaml
    /// </summary>
    public partial class ObjectProvider : UserControl
    {
        public static DataTemplateSelector _Selector = new PropertyEditorTemplateSelector();
        //private TypeViewModel _type;

        public ObjectProvider()
        {
            InitializeComponent();
        }

        public ObjectProvider(TemplateViewModel template): this()
        {
            this.TemplateViewModel = template;
        }

        //#region Type dependency property
        //public static DependencyProperty TypeProperty = DependencyProperty.Register("Type", typeof(Type), typeof(ObjectProvider),
        //    new PropertyMetadata((sender, args) =>
        //        {
        //            var type = args.NewValue as Type;
        //            var provider = sender as ObjectProvider;
        //            if(type != null && provider!=null)
        //            {
        //                provider.Constructors = type.GetConstructors();
        //            }
        //        }));

        //public Type Type
        //{
        //    get { return (Type)GetValue(TypeProperty); }
        //    set { SetValue(TypeProperty, value); }
        //}
        //#endregion

        //#region DependencyProperty 'Constructors'
        //public ConstructorInfo[] Constructors
        //{
        //    get
        //    {
        //        return (ConstructorInfo[])GetValue(_Constructors);
        //    }
        //    set
        //    {
        //        SetValue(_Constructors, value);
        //    }
        //}

        //public static readonly DependencyProperty _Constructors = DependencyProperty.Register("Constructors", typeof(ConstructorInfo[]), typeof(ObjectProvider), 
        //    new PropertyMetadata((sender, args)=>
        //    {
        //        var provider = (ObjectProvider)sender;
        //        provider.cmConstructors.ItemsSource = provider.Constructors;
        //    }));
        //#endregion

        #region Properties
        public TemplateViewModel TemplateViewModel{ get; set; }

        public TypeViewModel Type
        {
            get {

                return DataContext as TypeViewModel;
                //return _type; 
            }
            set
            {
                //_type = value;
                //this.grid.DataContext = _type;
                this.DataContext = value;
            }
        }
        
        public static DataTemplateSelector Selector
        {
            get
            {
                return _Selector;
            }
        }

        #region DependencyProperty 'CreateButtonVisibility'
        public Visibility CreateButtonVisibility
        {
            get
            {
                return (Visibility)GetValue(_CreateButtonVisibility);
            }
            set
            {
                SetValue(_CreateButtonVisibility, value);
            }
        }

        public static readonly DependencyProperty _CreateButtonVisibility = DependencyProperty.Register("CreateButtonVisibility", typeof(Visibility), typeof(ObjectProvider), new PropertyMetadata(Visibility.Collapsed));
        #endregion
        
        #endregion
            
        public static DependencyObject GetTemplatesControl(TemplateViewModel template, bool ignoreParameterlessConstructor)
        {
            var dataType = template.GetDataType();

            if( dataType !=null && 
                template.Data == null && 
                !ignoreParameterlessConstructor &&
                XamlSPViewModelService.HasParameterlessConstructor(dataType)
              )
                template.Data = XamlSPViewModelService.CreateDataObject(dataType);

            if(template.Data != null || dataType == null)
                return template.CreateControl();

            var provider = new ObjectProvider(template);
            provider.CreateButtonVisibility = Visibility.Visible;
            provider.Type = new TypeViewModel(dataType);

            return provider;
        }

        private void butGenerate_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                var newObj = Type.CreateInstance();
                TemplateViewModel.Data = newObj;
            }
            catch(Exception err)
            {
                txErrorReport.Text = err.Message; 
            }
            
            XAMLStylePadMainWindow.Instance.PreviewPanel.SetTemplate(TemplateViewModel);
        }
    }

    public class PropertyEditorTemplateSelector : DataTemplateSelector
    {
        public override DataTemplate SelectTemplate(object item, DependencyObject container)
        {
            DataTemplate res = null;
            if(container is FrameworkElement)
            {
                var visPar = VisualTreeHelper.GetParent(container);
                var resources = (visPar as FrameworkElement).Resources;
                //var parent = (container as FrameworkElement).TemplatedParent;
                
                Type type = null;
                if(item is VariableViewModel)
                    type = (item as VariableViewModel).Type;
                
                if(type != null)
                {
                    if(type.IsValueType)
                    {
                        if(type.IsEnum)
                        {
                            res =  (DataTemplate)resources["enumEditor"];
                            //res =  container
                        }
                        else if(type.IsPrimitive || type == typeof(decimal))
                        {
                            if(type == typeof(bool))
                            {
                                res =  (DataTemplate)resources["boolEditor"];
                            }
                            else
                                res =  (DataTemplate)resources["numberEditor"];
                        }
                        else if(type == typeof(DateTime))
                        {
                            res =  (DataTemplate)resources["datetimeEditor"];
                        }
                        else
                        { // struct
                            res = (DataTemplate)resources["objectEditor"];
                        }
                    }
                    else if(type == typeof(string))
                    {
                        res =  (DataTemplate)resources["stringEditor"];
                    }
                    else
                    {
                        res =  (DataTemplate)resources["objectEditor"];
                    }
                }

            }
            return res ?? base.SelectTemplate(item, container);
        }
    }
}
